﻿using System;

namespace Libs.Egucha
{
    struct Vector
    {
        public double x;
        public double y;

        public Vector(double par1X, double par2Y)
        {
            x = par1X;
            y = par2Y;
        }

        /// <summary>
        /// ベクトルを回転させる
        /// </summary>
        public void RotateVector(double radian)
        {
            double tx = -Math.Sin(radian) * y + Math.Cos(radian) * x;
            double ty = Math.Cos(radian) * y + Math.Sin(radian) * x;
            x = tx;
            y = ty;
        }

        public static Vector operator +(Vector par1, Vector par2)
        {
            par1.x += par2.x;
            par1.y += par2.y;
            return par1;
        }

        public static Vector operator -(Vector par1, Vector par2)
        {
            par1.x -= par2.x;
            par1.y -= par2.y;
            return par1;
        }

        public static Vector operator *(Vector par1, double par2)
        {
            par1.x *= par2;
            par1.y *= par2;
            return par1;
        }
    }

    struct PointD
    {
        public double x;
        public double y;

        public PointD(double par1X, double par2Y)
        {
            x = par1X;
            y = par2Y;
        }

        public static Vector operator +(PointD par1, PointD par2)
        {
            return new Vector(par1.x + par2.x, par1.y + par2.y);
        }

        public static Vector operator -(PointD par1, PointD par2)
        {
            return new Vector(par1.x - par2.x, par1.y - par2.y);
        }
    }

    struct Line
    {
        public PointD startPos;
        public PointD endPos;

        public Line(PointD par1StartPos, PointD par2EndPos)
        {
            startPos = par1StartPos;
            endPos = par2EndPos;
        }
    }

    struct Circle
    {
        public PointD pos;
        public double radius;

        public Circle(PointD par1Point, double par2Radius)
        {
            pos = par1Point;
            radius = par2Radius;
        }
    }

    struct Rect
    {
        public PointD leftTopPos;
        public PointD rightBottomPos;

        public Rect(PointD par1Point, PointD par2Point)
        {
            leftTopPos = par1Point;
            rightBottomPos = par2Point;
        }

        public Rect(PointD par1Point, double par2Width, double par3Height)
        {
            leftTopPos = par1Point;
            rightBottomPos = new PointD(par1Point.x + par2Width, par1Point.y + par3Height);
        }
    }


    static class Helper
    {
        /// <summary>
        /// System.Math.PIよりも正確な円周率の値を表す
        /// </summary>
        public const double PI = 3.14159265358979323846264338327950288d;

        /// <summary>
        /// 回転させたベクトルを返す
        /// </summary>
        public static Vector GetRotatedVector(Vector par1Vector, double radian)
        {
            par1Vector.RotateVector(radian);
            return par1Vector;
        }

        /// <summary>
        /// ラジアンから度(°)を求める
        /// </summary>
        public static double GetDegreeToRadian(double radian)
        {
            return radian * 180 / Math.PI;
        }

        /// <summary>
        /// 度（°）からラジアンを求める
        /// </summary>
        public static double GetRadianToDegree(double dgree)
        {
            return dgree * Math.PI / 180;
        }

        /// <summary>
        /// ベクトルの内積を求める
        /// </summary>
        public static double GetDotProduct(Vector par1Vector, Vector par2Vector)
        {
            return par1Vector.x * par2Vector.x + par1Vector.y * par2Vector.y;
        }

        /// <summary>
        /// ベクトルの外積を求める
        /// </summary>
        public static double GetCrossProduct(Vector par1Vector, Vector par2Vector)
        {
            return par1Vector.x * par2Vector.y - par1Vector.y * par2Vector.x;
        }

        /// <summary>
        /// ２点間の距離を求める
        /// </summary>
        public static double GetDistance(double par1Pos1X, double par2Pos1Y, double par3Pos2X, double par4Pos2Y)
        {
            return Math.Sqrt((par3Pos2X - par1Pos1X) * (par3Pos2X - par1Pos1X) + (par4Pos2Y - par2Pos1Y) * (par4Pos2Y - par2Pos1Y));
        }
    }
}
